import json
from py2neo import *
from django.shortcuts import render
from django.http import JsonResponse

graph = Graph(
    'http://localhost:7474',
    auth=('neo4j', '12345678'),
    name='medical.db'
)  # 连接数据库


def find_type(name):
    data_type = '对象'
    # 1
    with open("web/views/chatbot/dict/check.txt", encoding='utf8') as check_f:
        datafile = check_f.readlines()
        for line in datafile:
            if name == line.strip():
                data_type = '检查'
                break
    # 2
    with open("web/views/chatbot/dict/department.txt", encoding='utf8') as department_f:
        datafile = department_f.readlines()
        for line in datafile:
            if name == line.strip():
                data_type = '科室'
                break
    # 3
    with open("web/views/chatbot/dict/disease.txt", encoding='utf8') as disease_f:
        datafile = disease_f.readlines()
        for line in datafile:
            if name == line.strip():
                data_type = '疾病'
                break
    # 4
    with open("web/views/chatbot/dict/drug.txt", encoding='utf8') as drug_f:
        datafile = drug_f.readlines()
        for line in datafile:
            if name == line.strip():
                data_type = '医药'
                break
    # 5
    with open("web/views/chatbot/dict/food.txt", encoding='utf8') as food_f:
        datafile = food_f.readlines()
        for line in datafile:
            if name == line.strip():
                data_type = '食物'
                break
    # 6
    with open("web/views/chatbot/dict/producer.txt", encoding='utf8') as producer_f:
        datafile = producer_f.readlines()
        for line in datafile:
            if name == line.strip():
                data_type = '生产厂家'
                break
    # 7
    with open("web/views/chatbot/dict/symptom.txt", encoding='utf8') as symptom_f:
        datafile = symptom_f.readlines()
        for line in datafile:
            if name == line.strip():
                data_type = '病症'
                break

    return data_type


def search_all():
    # 定义data数组，存放节点信息
    data = []
    # 定义关系数组，存放节点间的关系
    links = []
    # 查询所有节点，并将节点信息取出存放在data数组中
    for n in graph.nodes:
        # 将节点信息转化为json格式，否则中文会不显示
        # print(n)
        nodesStr = json.dumps(graph.nodes[n], ensure_ascii=False)
        # 取出节点的name
        node_name = json.loads(nodesStr)['name']

        # 构造字典，存储单个节点信息
        dict = {
            'id': str(n),  # 防止重复节点
            'name': node_name,
            'symbolSize': 50,
            'category': '对象'
        }
        # 将单个节点信息存放在data数组中
        data.append(dict)
    # 查询所有关系，并将所有的关系信息存放在links数组中
    rps = graph.relationships
    for r in rps:
        # 取出开始节点的name
        source = str(rps[r].start_node['name'])
        # for i in data: #需要使用ID
        #     if source == i['name']:
        #         source = i['id']
        # 取出结束节点的name
        target = str(rps[r].end_node['name'])
        # for i in data: #需要使用ID
        #     if target == i['name']:
        #         target = i['id']
        # 取出开始节点的结束节点之间的关系
        name = str(type(rps[r]).__name__)
        # 构造字典存储单个关系信息
        dict = {
            'source': source,
            'target': target,
            'name': name
        }
        # 将单个关系信息存放进links数组中
        links.append(dict)
    # 输出所有节点信息
    # for item in data:
    #     print(item)
    # 输出所有关系信息
    # for item in links:
    #     print(item)
    # 将所有的节点信息和关系信息存放在一个字典中
    neo4j_data = {
        'data': data,
        'links': links
    }
    neo4j_data = json.dumps(neo4j_data)
    return neo4j_data


def search_all_category():
    data = []  # 定义data数组，存放节点信息
    links = []  # 定义关系数组，存放节点间的关系
    # 节点分类
    node_Check = graph.run('MATCH (n:Check) RETURN n LIMIT 500').data()
    node_Department = graph.run('MATCH (n:Department) RETURN n LIMIT 500').data()
    node_Disease = graph.run('MATCH (n:Disease) RETURN n LIMIT 500').data()
    node_Drug = graph.run('MATCH (n:Drug) RETURN n LIMIT 500').data()
    node_Food = graph.run('MATCH (n:Food) RETURN n LIMIT 500').data()
    node_Producer = graph.run('MATCH (n:Producer) RETURN n LIMIT 500').data()
    node_Symptom = graph.run('MATCH (n:Symptom) RETURN n LIMIT 500').data()

    node_count = 0
    for n in node_Check:
        nodesStr = json.dumps(n, ensure_ascii=False)  # 将节点信息转化为json格式，否则中文会不显示
        node_name = json.loads(nodesStr)
        node_name = node_name['n']['name']  # 取出节点的name
        # print(node_name)
        dict = {
            'id': node_count,  # 防止重复节点
            'name': node_name,
            'symbolSize': 50,
            'category': 'Check'
        }
        data.append(dict)  # 将单个节点信息存放在data数组中
        node_count = node_count + 1
    for n in node_Department:
        nodesStr = json.dumps(n, ensure_ascii=False)  # 将节点信息转化为json格式，否则中文会不显示
        node_name = json.loads(nodesStr)
        node_name = node_name['n']['name']  # 取出节点的name
        # print(node_name)
        dict = {
            'id': node_count,  # 防止重复节点
            'name': node_name,
            'symbolSize': 50,
            'category': 'Department'
        }
        data.append(dict)  # 将单个节点信息存放在data数组中
        node_count = node_count + 1
    for n in node_Disease:
        nodesStr = json.dumps(n, ensure_ascii=False)  # 将节点信息转化为json格式，否则中文会不显示
        node_name = json.loads(nodesStr)
        node_name = node_name['n']['name']  # 取出节点的name
        # print(node_name)
        dict = {
            'id': node_count,  # 防止重复节点
            'name': node_name,
            'symbolSize': 50,
            'category': 'Disease'
        }
        data.append(dict)  # 将单个节点信息存放在data数组中
        node_count = node_count + 1
    for n in node_Drug:
        nodesStr = json.dumps(n, ensure_ascii=False)  # 将节点信息转化为json格式，否则中文会不显示
        node_name = json.loads(nodesStr)
        node_name = node_name['n']['name']  # 取出节点的name
        # print(node_name)
        dict = {
            'id': node_count,  # 防止重复节点
            'name': node_name,
            'symbolSize': 50,
            'category': 'Drug'
        }
        data.append(dict)  # 将单个节点信息存放在data数组中
        node_count = node_count + 1
    for n in node_Food:
        nodesStr = json.dumps(n, ensure_ascii=False)  # 将节点信息转化为json格式，否则中文会不显示
        node_name = json.loads(nodesStr)
        node_name = node_name['n']['name']  # 取出节点的name
        # print(node_name)
        dict = {
            'id': node_count,  # 防止重复节点
            'name': node_name,
            'symbolSize': 50,
            'category': 'Food'
        }
        data.append(dict)  # 将单个节点信息存放在data数组中
        node_count = node_count + 1
    for n in node_Producer:
        nodesStr = json.dumps(n, ensure_ascii=False)  # 将节点信息转化为json格式，否则中文会不显示
        node_name = json.loads(nodesStr)
        node_name = node_name['n']['name']  # 取出节点的name
        # print(node_name)
        dict = {
            'id': node_count,  # 防止重复节点
            'name': node_name,
            'symbolSize': 50,
            'category': 'Producer'
        }
        data.append(dict)  # 将单个节点信息存放在data数组中
        node_count = node_count + 1
    for n in node_Symptom:
        nodesStr = json.dumps(n, ensure_ascii=False)  # 将节点信息转化为json格式，否则中文会不显示
        node_name = json.loads(nodesStr)
        node_name = node_name['n']['name']  # 取出节点的name
        # print(node_name)
        dict = {
            'id': node_count,  # 防止重复节点
            'name': node_name,
            'symbolSize': 50,
            'category': 'Symptom'
        }
        data.append(dict)  # 将单个节点信息存放在data数组中
        node_count = node_count + 1

    # 查询所有关系，并将所有的关系信息存放在links数组中
    rps = graph.relationships
    # count = 0
    for r in rps:
        # count = count + 1
        # if count > 5000:
        #     break
        source = str(rps[r].start_node['name'])  # 取出开始节点的name
        target = str(rps[r].end_node['name'])
        name = str(type(rps[r]).__name__)  # 取出开始节点的结束节点之间的关系
        # 构造字典存储单个关系信息
        source_id = -1
        target_id = -1
        for node in data:
            if node['name'] == source:
                source_id = node['id']
            if node['name'] == target:
                target_id = node['id']
            if source_id >= 0 and target_id >= 0:
                break

        dict = {
            'source': source_id,
            'target': target_id,
            'name': name
        }
        links.append(dict)  # 将单个关系信息存放进links数组中
    neo4j_data = {
        'data': data,
        'links': links
    }
    neo4j_data = json.dumps(neo4j_data)
    return neo4j_data


def search_one(value):
    # 定义data数组存储节点信息
    data = []
    # 定义links数组存储关系信息
    links = []
    # 查询节点是否存在
    node = graph.run('MATCH(n{name:"' + value + '"}) return n').data()
    # 如果节点存在len(node)的值为1不存在的话len(node)的值为0
    node_count = 0
    if len(node):
        # 如果该节点存在将该节点存入data数组中
        this = json.dumps(node[0], ensure_ascii=False)
        this = json.loads(this)
        t = find_type(value)
        # 构造字典存放节点信息
        dict = {
            'id': node_count,
            'name': value,
            'symbolSize': 50,
            'category': t
        }
        data.append(dict)
        # 查询与该节点有关的节点，无向，步长为1，并返回这些节点
        nodes = graph.run('MATCH(n{name:"' + value + '"})<-->(m) return m').data()
        # 查询该节点所涉及的所有relationship，无向，步长为1，并返回这些relationship
        reps = graph.run('MATCH(n{name:"' + value + '"})<-[rel]->(m) return rel').data()
        # 处理节点信息

        relate_node = []
        for n in nodes:
            # 将节点信息的格式转化为json
            node = json.dumps(n, ensure_ascii=False)
            node = json.loads(node)
            # 取出节点信息中的name
            name = str(node['m']['name'])
            if name in relate_node:
                continue
            t = find_type(name)
            # 构造字典存放单个节点信息
            node_count = node_count + 1
            dict = {
                'id': node_count,
                'name': name,
                'symbolSize': 50,
                'category': t
            }
            # 将单个节点信息存储进data数组中
            data.append(dict)
            relate_node.append(name)
        # 处理relationship
        for r in reps:
            source = str(r['rel'].start_node['name'])
            target = str(r['rel'].end_node['name'])
            name = str(r['rel']['name'])

            source_id = -1
            target_id = -1
            for node in data:
                if node['name'] == source:
                    source_id = node['id']
                if node['name'] == target:
                    target_id = node['id']
                if source_id >= 0 and target_id >= 0:
                    break

            dict = {
                'source': source_id,
                'target': target_id,
                'name': name
            }
            links.append(dict)
        # 构造字典存储data和links
        search_neo4j_data = {
            'data': data,
            'links': links
        }
        # 将dict转化为json格式
        search_neo4j_data = json.dumps(search_neo4j_data)
        return search_neo4j_data
    else:
        # print("查无此节点")
        return 0


def get_graph(request):
    ctx = {}
    neo4j_data = search_one('放射性肺炎')
    name = request.GET.get("name") or ""
    if name and name != "":
        # 有要查询的节点名
        neo4j_data = search_one(name)

    return render(request, 'visualization.html', {'neo4j_data': neo4j_data, 'ctx': ctx})
